package com.skyjing.askit.java;

import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;

import java.io.File;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 使用系统下载器downloadmanager下载文件
 */
public class AsDownloadManagerUitls {

    private DownloadManager downloadManager;
    private Context context;
    private long downloadId;
    private String url;
    private String name;
    private String path;
    private String savePath;
    private ListenerImpl listener;
    private Timer timer;
    private TimerTask task;
    private int refreshTime = 500;
    private DownloadManager.Request request;
    public static final int SAVE_FILE_DOWNLOAD = 0;
    public static final int SAVE_FILE_DCIM = 1;
    public static final int SAVE_FILE_MUSIC = 2;
    public static final int SAVE_FILE_RINGTONES = 3;
    public static final int SAVE_FILE_ALARMS = 4;
    public static final int SAVE_FILE_PICTURES = 5;
    public static final int SAVE_FILE_MOVIES = 6;
    public static final int SAVE_FILE_DOCUMENTS = 7;
    public static final int SAVE_FILE_SCREENSHOTS = 8;
    public static final int SAVE_FILE_AUDIOBOOKS = 9;
    public static final int SAVE_FILE_NOTIFICATIONS = 10;
    public static final int SAVE_FILE_PODCASTS = 11;

    public AsDownloadManagerUitls(Context context, String url) {
        this(context, url, "", getFileNameByUrl(url) , 0);
    }

    public AsDownloadManagerUitls(Context context, String url , int type) {
        this(context, url, "", getFileNameByUrl(url) , type);
    }

    public AsDownloadManagerUitls(Context context, String url, String name) {
        this(context, url, "", name , 0);
    }

    public AsDownloadManagerUitls(Context context, String url, String name , int type) {
        this(context, url, "", name , type);
    }


    public AsDownloadManagerUitls(Context context, String url, String savePath, String name , int type) {
        this.context = context;
        this.url = url;
        this.name = name;
        this.savePath = savePath;
        request = new DownloadManager.Request(Uri.parse(url));
        request.setTitle(name)
                .setDescription("文件正在下载中......");

        File file = null;
        if (savePath.isEmpty()) {
            switch (type){
                case SAVE_FILE_DCIM:{
                    file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DCIM), name);
                }break;
                case SAVE_FILE_MUSIC:{
                    file = new File(context.getExternalFilesDir(Environment.DIRECTORY_MUSIC), name);
                }break;
                case SAVE_FILE_RINGTONES:{
                    file = new File(context.getExternalFilesDir(Environment.DIRECTORY_RINGTONES), name);
                }break;
                case SAVE_FILE_ALARMS:{
                    file = new File(context.getExternalFilesDir(Environment.DIRECTORY_ALARMS), name);
                }break;
                case SAVE_FILE_PICTURES:{
                    file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), name);
                }break;
                case SAVE_FILE_MOVIES:{
                    file = new File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), name);
                }break;
                case SAVE_FILE_DOCUMENTS:{
                    file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), name);
                }break;
                case SAVE_FILE_SCREENSHOTS:{
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                        file = new File(context.getExternalFilesDir(Environment.DIRECTORY_SCREENSHOTS), name);
                    }
                }break;
                case SAVE_FILE_AUDIOBOOKS:{
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                        file = new File(context.getExternalFilesDir(Environment.DIRECTORY_AUDIOBOOKS), name);
                    }
                }break;
                case SAVE_FILE_NOTIFICATIONS:{
                    file = new File(context.getExternalFilesDir(Environment.DIRECTORY_NOTIFICATIONS), name);
                }break;
                case SAVE_FILE_PODCASTS:{
                    file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PODCASTS), name);
                }break;
                case SAVE_FILE_DOWNLOAD:
                default:{
                    file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), name);
                }
            }
        } else {
            file = new File(savePath, name);
        }
        request.setDestinationUri(Uri.fromFile(file));
        path = file.getAbsolutePath();
        downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    }

    public AsDownloadManagerUitls setListener(ListenerImpl listener) {
        this.listener = listener;
        return this;
    }

    public AsDownloadManagerUitls setTitle(String title) {
        request.setTitle(title);
        return this;
    }

    public AsDownloadManagerUitls setDescription(String des) {
        request.setDescription(des);
        return this;
    }

    //表示允许MediaScanner扫描到这个文件，默认不允许。
    public AsDownloadManagerUitls MediaScanner() {
        request.allowScanningByMediaScanner();
        return this;
    }

    public AsDownloadManagerUitls addRequestHeader(String header, String value) {
        request.addRequestHeader(header, value);
        return this;
    }

    public AsDownloadManagerUitls setMimeType(String type) {
        request.setMimeType(type);
        return this;
    }

    public AsDownloadManagerUitls setNotificationVisibility(int type) {
        request.setNotificationVisibility(type);
        return this;
    }

    public AsDownloadManagerUitls setAllowedOverRoaming(boolean isAllOwed) {
        request.setAllowedOverRoaming(isAllOwed);
        return this;
    }

    //显示在下载界面，即下载后的文件在系统下载管理里显示
    public AsDownloadManagerUitls setVisibleInDownloadsUi(boolean isShow) {
        request.setVisibleInDownloadsUi(isShow);
        return this;
    }

    public AsDownloadManagerUitls setAllowedNetworkTypes(int type) {
        request.setAllowedNetworkTypes(type);
        return this;
    }

    public AsDownloadManagerUitls setRefreshTime(int time) {
        refreshTime = time;
        return this;
    }


    /**
     * 开始下载
     */
    public void download() {
        //将下载请求加入下载队列，加入下载队列后会给该任务返回一个long型的id，通过该id可以取消任务，重启任务、获取下载的文件等等
        if (downloadManager != null) {
            if (listener != null) {
                listener.onPrepare();
            }
            downloadId = downloadManager.enqueue(request);

            //监听下载进度
            final DownloadManager.Query query = new DownloadManager.Query();
            timer = new Timer();
            task = new TimerTask() {
                @Override
                public void run() {
                    Cursor cursor = downloadManager.query(query.setFilterById(downloadId));
                    if (cursor != null && cursor.moveToFirst()) {
                        if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
                                == DownloadManager.STATUS_SUCCESSFUL) {
//                        if (listener != null) {
//                            listener.onDownloadPercent();
//                        }
                            task.cancel();
                        }
                        String title = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_TITLE));
                        String address = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                        long currentSize = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                        long totalSize = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
                        float pro = (currentSize * 100f / totalSize);
                        if (totalSize > 0) {
                            if (listener != null) {
                                listener.onDownloadPercent(totalSize, currentSize);
                            }
                        }
                    }
                    assert cursor != null;
                    cursor.close();
                }
            };
            //500毫秒查询一次
            timer.schedule(task, 0, refreshTime);
            task.run();
        }

        //注册广播接收者，监听下载状态
        context.registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    }

    private void download2() {
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
        //移动网络情况下是否允许漫游
        request
//                .setAllowedOverRoaming(false)
                //添加请求头
//                .addRequestHeader(String header, String value)
                //在通知栏中显示，默认就是显示的,不设置，下载完成后就不会在通知栏显示提示
//                .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
                .setTitle(name)
                .setDescription("文件正在下载中......")
                /**
                 * 这是安卓.apk文件的类型。有些机型必须设置此方法，才能在下载完成后，
                 * 点击通知栏的Notification时，才能正确的打开安装界面。
                 * 不然会弹出一个Toast（can not open file）.其他文件类型的MimeType
                 */
//                .setMimeType("application/vnd.android.package-archive")
//                .setVisibleInDownloadsUi(true)
                .allowScanningByMediaScanner();//表示允许MediaScanner扫描到这个文件，默认不允许。
        /**
         * 表示下载允许的网络类型，默认在任何网络下都允许下载。
         * 有NETWORK_MOBILE、NETWORK_WIFI、NETWORK_BLUETOOTH三种及其组合可供选择。如果只允许wifi下载，而当前网络为3g，则下载会等待。
         * request.setAllowedOverRoaming(boolean allow)移动网络情况下是否允许漫游。
         */
//        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);

//        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).mkdir();

        //设置下载的路径
        //该路径是SD卡中的download文件夹
//        File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), name);
        //该路径为 path= /storage/emulated/0/Android/data/com.skyjing.astools/files/测试/C10B2237586138DF3909E47B981B73F9.apk
//        File file = new File( context.getExternalFilesDir(null) + File.separator + "测试", name);
        File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), name);
        request.setDestinationUri(Uri.fromFile(file));
        path = file.getAbsolutePath();

        //获取DownloadManager
        if (downloadManager == null) {
            downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
        }
        //将下载请求加入下载队列，加入下载队列后会给该任务返回一个long型的id，通过该id可以取消任务，重启任务、获取下载的文件等等
        if (downloadManager != null) {
            if (listener != null) {
                listener.onPrepare();
            }
            downloadId = downloadManager.enqueue(request);

            //监听下载进度
            final DownloadManager.Query query = new DownloadManager.Query();
            timer = new Timer();
            task = new TimerTask() {
                @Override
                public void run() {
                    Cursor cursor = downloadManager.query(query.setFilterById(downloadId));
                    if (cursor != null && cursor.moveToFirst()) {
                        if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
                                == DownloadManager.STATUS_SUCCESSFUL) {
//                        if (listener != null) {
//                            listener.onDownloadPercent();
//                        }
                            task.cancel();
                        }
                        String title = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_TITLE));
                        String address = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                        long currentSize = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                        long totalSize = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
                        float pro = (currentSize * 100f / totalSize);
                        if (totalSize > 0) {
                            if (listener != null) {
                                listener.onDownloadPercent(totalSize, currentSize);
                            }
                        }
                    }
                    assert cursor != null;
                    cursor.close();
                }
            };
            //500毫秒查询一次
            timer.schedule(task, 0, refreshTime);
            task.run();
        }

        //注册广播接收者，监听下载状态
        context.registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    }

    public void cancle() {
        context.unregisterReceiver(receiver);
        task.cancel();
        downloadManager.remove(downloadId);
    }

    //广播监听下载的各个状态
    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            DownloadManager.Query query = new DownloadManager.Query();
            //通过下载的id查找
            query.setFilterById(downloadId);
            Cursor cursor = downloadManager.query(query);
            if (cursor.moveToFirst()) {
                int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
                switch (status) {
                    //下载暂停
                    case DownloadManager.STATUS_PAUSED:
                        break;
                    //下载延迟
                    case DownloadManager.STATUS_PENDING:
                        break;
                    //正在下载
                    case DownloadManager.STATUS_RUNNING:
                        break;
                    //下载完成
                    case DownloadManager.STATUS_SUCCESSFUL:
                        task.cancel();
                        String title = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_TITLE));
                        String address = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                        long currentSize = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
                        long totalSize = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
                        float pro = (currentSize * 100f / totalSize);
                        if (listener != null) {
                            if (totalSize > 0) {
                                listener.onDownloadPercent(totalSize, currentSize);
                            }
                            listener.onSuccess(path);
                        }
                        cursor.close();
                        context.unregisterReceiver(receiver);
                        break;
                    //下载失败
                    case DownloadManager.STATUS_FAILED:
                        if (listener != null) {
                            listener.onFailed(new Exception("下载失败"));
                        }
                        task.cancel();
                        cursor.close();
                        context.unregisterReceiver(receiver);
                        break;
                }
            }
        }
    };


    // ——————————————————————私有方法———————————————————————

    /**
     * 通过URL获取文件名
     *
     * @param url
     * @return
     */
    private static final String getFileNameByUrl(String url) {
        String filename = url.substring(url.lastIndexOf("/") + 1);
        filename = filename.substring(0, filename.indexOf("?") == -1 ? filename.length() : filename.indexOf("?"));
        return filename;
    }

    public interface DownloadManagerUitlsListener {
        void onPrepare();

        void onSuccess(String path);

        void onFailed(Throwable throwable);

        void onDownloadPercent(long totalSize, long currentSize);
    }

    public static class ListenerImpl implements DownloadManagerUitlsListener {

        @Override
        public void onPrepare() {

        }

        @Override
        public void onSuccess(String path) {

        }

        @Override
        public void onFailed(Throwable throwable) {

        }

        @Override
        public void onDownloadPercent(long totalSize, long currentSize) {

        }
    }
}
